/*
 * TimePanel.java
 *
 * Created on 14 July 2003, 08:50
 * Copyright (C) 2003, Velocityme Partnership
 */

package com.velocityme.client.gui.time;

import com.velocityme.client.gui.calendar.CalendarDatePanel;
import com.velocityme.client.gui.exception.ExceptionWindow;
import com.velocityme.client.gui.node.contactable.ContactableTreeCellRenderer;
import com.velocityme.client.utility.*;
import com.velocityme.interfaces.*;
import com.velocityme.utility.InvalidKeyException;
import com.velocityme.valueobjects.*;
import java.io.*;
import java.rmi.RemoteException;
import java.util.*;
import javax.ejb.CreateException;
import javax.naming.NamingException;
import javax.swing.JFileChooser;
import javax.swing.text.html.HTMLDocument;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

/**
 *
 * @author  Robert Crida Work
 */
public class TimeReportPanel extends javax.swing.JPanel {
    
    private KeySession m_key;
    private NodePK m_nodePK;
    private CalendarDatePanel m_startDatePanel;
    private CalendarDatePanel m_stopDatePanel;
    private TreeModel m_contactableTreeModel;
    private ByteArrayOutputStream m_currentHtmlOutputStream;
    
    /** Creates new form TimePanel */
    public TimeReportPanel(KeySession p_key, NodePK p_nodePK) {
        m_key = p_key;
        m_nodePK = p_nodePK;
        
        try {
            m_contactableTreeModel = StatelessRemoteClientSessionUtil.getSession().getContactableValueTree(m_key);
        }
        catch(Exception e) {
            ExceptionWindow.showError(e);
        }
        initComponents();
        m_startDatePanel = new CalendarDatePanel();
        m_stopDatePanel = new CalendarDatePanel();
        java.awt.GridBagConstraints gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 2);
        jPanel1.add(m_startDatePanel, gridBagConstraints);
        jPanel1.add(m_stopDatePanel, gridBagConstraints);
        
        Date now = new Date();
        m_startDatePanel.setDate(now);
        m_stopDatePanel.setDate(now);
    }
    
    void refresh() {
        try {
            jTextFieldNode.setText(StatelessRemoteClientSessionUtil.getSession().getNodePathName(m_key, m_nodePK));
            jCheckBoxRecursive.setSelected(true);
        }
        catch(NamingException e) {
            ExceptionWindow.showError(e);
        }
        catch(CreateException e) {
            ExceptionWindow.showError(e);
        }
        catch(RemoteException e) {
            ExceptionWindow.showError(e);
        }
        catch(InvalidKeyException e) {
            ExceptionWindow.showError(e);
        }
    }
    
    private ContactablePK[] getContactablePks() {
        TreePath[] addPaths = jTreeContactable.getSelectionPaths();
        ContactablePK[] pks;
        if (addPaths != null) {
            pks = new ContactablePK[addPaths.length];
            for (int i = 0; i < addPaths.length; i++) {
                pks[i] = ((ContactableValue)((DefaultMutableTreeNode)addPaths[i].getLastPathComponent()).getUserObject()).getPrimaryKey();
            }
        }
        else
            pks = new ContactablePK[0];
        return pks;
    }
    
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    private void initComponents() {//GEN-BEGIN:initComponents
        java.awt.GridBagConstraints gridBagConstraints;

        jPanel1 = new javax.swing.JPanel();
        jLabelNode = new javax.swing.JLabel();
        jTextFieldNode = new javax.swing.JTextField();
        jLabelContactable = new javax.swing.JLabel();
        jScrollPane2 = new javax.swing.JScrollPane();
        jTreeContactable = new javax.swing.JTree(m_contactableTreeModel);
        jTreeContactable.setCellRenderer(new ContactableTreeCellRenderer());
        jLabelRecursive = new javax.swing.JLabel();
        jLabelInclusions = new javax.swing.JLabel();
        jCheckBoxRecursive = new javax.swing.JCheckBox();
        jPanel3 = new javax.swing.JPanel();
        jCheckBoxTaskSummary = new javax.swing.JCheckBox();
        jCheckBoxTypeSummary = new javax.swing.JCheckBox();
        jCheckBoxStateSummary = new javax.swing.JCheckBox();
        jCheckBoxTimeEntries = new javax.swing.JCheckBox();
        jLabelStart = new javax.swing.JLabel();
        jLabelStop = new javax.swing.JLabel();
        jPanel2 = new javax.swing.JPanel();
        jButtonSearch = new javax.swing.JButton();
        jButtonSave = new javax.swing.JButton();
        jButtonClose = new javax.swing.JButton();
        jScrollPaneDescription = new javax.swing.JScrollPane();
        jEditorPaneLog = new javax.swing.JEditorPane();

        setLayout(new java.awt.BorderLayout());

        addComponentListener(new java.awt.event.ComponentAdapter() {
            public void componentShown(java.awt.event.ComponentEvent evt) {
                formComponentShown(evt);
            }
        });

        jPanel1.setLayout(new java.awt.GridBagLayout());

        jPanel1.setMinimumSize(new java.awt.Dimension(0, 0));
        jLabelNode.setText("Node:");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 2);
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        jPanel1.add(jLabelNode, gridBagConstraints);

        jTextFieldNode.setEditable(false);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 2);
        gridBagConstraints.weightx = 1.0;
        jPanel1.add(jTextFieldNode, gridBagConstraints);

        jLabelContactable.setText("Contactables:");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 2);
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        jPanel1.add(jLabelContactable, gridBagConstraints);

        jScrollPane2.setPreferredSize(new java.awt.Dimension(3, 66));
        jTreeContactable.setRootVisible(false);
        jTreeContactable.setShowsRootHandles(true);
        jScrollPane2.setViewportView(jTreeContactable);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 2);
        gridBagConstraints.weighty = 0.5;
        jPanel1.add(jScrollPane2, gridBagConstraints);

        jLabelRecursive.setText("Recursive:");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 2);
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        jPanel1.add(jLabelRecursive, gridBagConstraints);

        jLabelInclusions.setText("Inclusions:");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 2);
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        jPanel1.add(jLabelInclusions, gridBagConstraints);

        jCheckBoxRecursive.setText("Recursive");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 2);
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        jPanel1.add(jCheckBoxRecursive, gridBagConstraints);

        jPanel3.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT, 2, 0));

        jCheckBoxTaskSummary.setText("Tasks");
        jPanel3.add(jCheckBoxTaskSummary);

        jCheckBoxTypeSummary.setText("Types");
        jPanel3.add(jCheckBoxTypeSummary);

        jCheckBoxStateSummary.setText("State Summary");
        jPanel3.add(jCheckBoxStateSummary);

        jCheckBoxTimeEntries.setText("Entries");
        jPanel3.add(jCheckBoxTimeEntries);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        jPanel1.add(jPanel3, gridBagConstraints);

        jLabelStart.setText("Start:");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 2);
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        jPanel1.add(jLabelStart, gridBagConstraints);

        jLabelStop.setText("Stop:");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 2);
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        jPanel1.add(jLabelStop, gridBagConstraints);

        add(jPanel1, java.awt.BorderLayout.NORTH);

        jPanel2.setLayout(new java.awt.GridLayout(1, 0));

        jButtonSearch.setText("Search");
        jButtonSearch.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonSearchActionPerformed(evt);
            }
        });

        jPanel2.add(jButtonSearch);

        jButtonSave.setText("Save");
        jButtonSave.setEnabled(false);
        jButtonSave.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonSaveActionPerformed(evt);
            }
        });

        jPanel2.add(jButtonSave);

        jButtonClose.setText("Close");
        jButtonClose.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonCloseActionPerformed(evt);
            }
        });

        jPanel2.add(jButtonClose);

        add(jPanel2, java.awt.BorderLayout.SOUTH);

        jScrollPaneDescription.setPreferredSize(new java.awt.Dimension(3, 160));
        jScrollPaneDescription.setViewportView(jEditorPaneLog);

        add(jScrollPaneDescription, java.awt.BorderLayout.CENTER);

    }//GEN-END:initComponents

    private void jButtonCloseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonCloseActionPerformed
        // Add your handling code here:
        getParent().remove(this);                        
    }//GEN-LAST:event_jButtonCloseActionPerformed

    private void jButtonSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonSaveActionPerformed
        // Add your handling code here:
        JFileChooser chooser = new JFileChooser();
        chooser.setDialogType(JFileChooser.SAVE_DIALOG);
        int returnVal = chooser.showOpenDialog(this);
        if(returnVal == JFileChooser.APPROVE_OPTION) {
            try {
                FileOutputStream file = new FileOutputStream(chooser.getSelectedFile());
                file.write(m_currentHtmlOutputStream.toByteArray());
                file.close();
            }
            catch(java.io.IOException e) {
                ExceptionWindow.showError(e);
            }
        }
    }//GEN-LAST:event_jButtonSaveActionPerformed

    private void jButtonSearchActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonSearchActionPerformed
        // Add your handling code here:
        jButtonSave.setEnabled(false);
        try {
            ContactablePK[] contactablePKs = getContactablePks();
            boolean recursive = jCheckBoxRecursive.isSelected();
            boolean taskSummary = jCheckBoxTaskSummary.isSelected();
            boolean typeSummary = jCheckBoxTypeSummary.isSelected();
            boolean stateSummary = jCheckBoxStateSummary.isSelected();
            boolean entries = jCheckBoxTimeEntries.isSelected();
            Date start = m_startDatePanel.getDate();
            Date stop = m_stopDatePanel.getDate();
            long time = stop.getTime();
            stop.setTime(time + 999 + 59*1000 + 59*60*1000 + 23*60*60*1000); // Make time 23h59:59.999
            String text = StatelessRemoteClientSessionUtil.getSession().getNodeSearchTimeLogXML(m_key, m_nodePK, contactablePKs, recursive, taskSummary, typeSummary, stateSummary, entries, start, stop);
            Transformer transformer = TransformerFactory.newInstance().newTransformer(new StreamSource("timeLog.xsl"));
            ByteArrayInputStream inputStream = new ByteArrayInputStream(text.getBytes());
            Source source = new StreamSource(inputStream);
            m_currentHtmlOutputStream = new ByteArrayOutputStream();
            Result output = new StreamResult(m_currentHtmlOutputStream);
            transformer.transform(source, output);
            jEditorPaneLog.setEditable(false);
            jEditorPaneLog.setContentType("text/html");
            HTMLDocument doc = (HTMLDocument)((HTMLEditorKit)jEditorPaneLog.getEditorKit()).createDefaultDocument();
            doc.putProperty("IgnoreCharsetDirective", new Boolean(true));
            jEditorPaneLog.read(new ByteArrayInputStream(m_currentHtmlOutputStream.toByteArray()), doc);
            jButtonSave.setEnabled(true);
        }
        catch(RemoteException e) {
            ExceptionWindow.showError(e);
        }
        catch(Exception e) {
            ExceptionWindow.showError(e);
        }        
    }//GEN-LAST:event_jButtonSearchActionPerformed

    private void formComponentShown(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_formComponentShown
        // Add your handling code here:
        refresh();
    }//GEN-LAST:event_formComponentShown
    
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButtonClose;
    private javax.swing.JButton jButtonSave;
    private javax.swing.JButton jButtonSearch;
    private javax.swing.JCheckBox jCheckBoxRecursive;
    private javax.swing.JCheckBox jCheckBoxStateSummary;
    private javax.swing.JCheckBox jCheckBoxTaskSummary;
    private javax.swing.JCheckBox jCheckBoxTimeEntries;
    private javax.swing.JCheckBox jCheckBoxTypeSummary;
    private javax.swing.JEditorPane jEditorPaneLog;
    private javax.swing.JLabel jLabelContactable;
    private javax.swing.JLabel jLabelInclusions;
    private javax.swing.JLabel jLabelNode;
    private javax.swing.JLabel jLabelRecursive;
    private javax.swing.JLabel jLabelStart;
    private javax.swing.JLabel jLabelStop;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JScrollPane jScrollPaneDescription;
    private javax.swing.JTextField jTextFieldNode;
    private javax.swing.JTree jTreeContactable;
    // End of variables declaration//GEN-END:variables
    
}
